package wodegua.d18_collection;

/**
 * 集合体系结构
 * ●Collection代表单列集合，每个元案(数据)只包含一个值。
 * Map代表双列集合，每个元素包含两个值(键值对)。
 */

/**
 * Collection集合体系
 * 接口
 * Collection<E>
 * 1.List<E>
 * 2.Set<E>
 *
 * 实现类
 * List<E> -> ArrayList<E>、LinkedList<E>
 * Set<E> -> TreeSet<E>、HashSet<E>->LinkedHashSet<E>
 *
 * Collection集合特点
 * ● List系列集合:添加的元素是有序、可重复、有引。
 * ArrayÈist、LinekdList:有序、可重复、有索引。
 * Set系列集合:添加的元素是无序、不重复、无索引。
 * ◆ Hashset:无序、不重复、无索引;
 * ◆ LinkedHashset:有序、不重复、无索引。
 * Treeset:按照大小默认升序排序、不重复、无索引。
 */

/**
 * 迭代器概述
 * 迭代器是用来遍历集合的专用方式(数组没有选代器)，在Java中选代器的代表是Iterator
 * Collection集合获取选代器的方法
 * 方法名称
 * 说明
 * Iterator<E>iterator() 逐阳合中的选代器对象，该选代器对象默认那向当前楚合的第一个元腐
 * Iterator选代器中的常用方法
 * 方法名称
 * boole hashNext()
 * E next()
 * 说明
 * 润问当前位盟超否有元察部在，存在返网，不存在返日fa1s
 * 获职当前位置的元素，并同到将选代器对象指向下一个元家处。
 */

/**
 * 增强for循环
 * 格式:
 * for(元素的数据类型 变量名:数组或者集合){
 * Collection<String>c= new ArrayList<>();
 * for(String s : c)(
 * 增强for可以用来遍历集合或者数组。
 * 增强for遍历集合，本质就是迭代器遍历集合的简化写法。
 */

/**
 * Lambda表达式遍历集合
 * 得益于JDK 8开始的新技术Lambda表达式，提供了一种更简单、更直接的方式来遍历集合。需要使用Collection的如下方法来完成
 * 方法名称
 * 说明
 * default void forEach(consumerc? super T) action)结合1ambda遍历集合
 */

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 1、如果希望记住元素的添加顺序，需要存储重复的元素，又要频繁的根据索引查询数据?
 * 用ArrayList集合(有序、可重复、有索引)，底层基于数组的。(常用)
 * 2、如果希望记住元素的添加顺序，且增删首尾数据的情况较多?
 * 用LinkedList集合(有序、可重复、有索引)，底层基于双链表实现的。
 * 3.如果不在意元素顺序，也没有重复元素需要存储，只希望增制改查都快?
 * 用Hashset集合(无序，不重复，无索引)，底层基于哈希表实现的。(常用)
 * 4.如果希望记住元素的添加顺序，也没有重复元素需要存储，且希望增删改查都快?
 * 用LinkedHashset集合(有序，不重复，无索引)，底层基于哈表和双链表。
 * 5.如果要对元素进行排序，也没有重复元素需要存储?且希望增删改查都快?
 * 用Treeset集合，基于红黑树实现。
 */

/**
 * 集合的并发修改异常
 * 使用迭代器遍历集合时，又同时在删除集合中的数据，程序就会出现并发修改异常的错误。
 * 由于增强for循环遍历集合就是迭代器遍历集合的简化写法，因此，使用增强for循环遍历集合，又在同时删除集合中的数据时，程序也会出现并发修改异常的错误
 *
 * 怎么保证遍历集合同时删除数据时不出bug?
 * ●使用迭代器遍历集合，但用迭代器自己的删除方法制除数据即可。
 * 如果能用for循环遍历时:可以倒着遍历并制除;或者从前往后遍历，但删除元素后做i-操作
 */
public class CollectionTest {
    public static void main(String[] args) {

        /**
         * 目标:理解集合的并发修改并常问题。并解决
         */
        //// 需求:找出集合中全部带“李”的名字，并从集合中到除。
        List<String> l = new ArrayList<>();
        l.add("王麻子");
        l.add("小李子");
        l.add("李爱花");

        Iterator<String> it = l.iterator();
        while (it.hasNext()) {
            String name = it.next();
            if (name.contains("李")) {
                // list.remove(nome)://并发修改异常的错误。
                it.remove(); //删除选代器当前游历到的数据，每影除一个数据后，相当
            }
        }
        System.out.println(l);

//        for (int i = 0; i < l.size(); i++) {
//            String name = l.get(i);
//            if (name.contains("李")) {
//                l.remove(name);
//                i--;
//            }
//        }
//        System.out.println(l);

        //使用增强for循环遍历集合并制除数据，没有办法解决bug.
        for (String name : l) {
            if (name.contains("李")) {
                l.remove(name);
            }
        }
        System.out.println(l);
        l.forEach(name -> {
            if (name.contains("李")) {
                l.remove(name);
            }
        });
        System.out.println(l);

    }
}